home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / sviluppo / svilupp2 / gmsppr10.lha / CreateSpriteList.c < prev    next >
C/C++ Source or Header  |  1996-05-20  |  37KB  |  1,581 lines

  1. #ifndef EXEC_MEMORY_H
  2. #include <exec/memory.h>
  3. #endif
  4.  
  5. #ifndef UTILITY_UTILITY_H
  6. #include <utility/utility.h>
  7. #endif
  8.  
  9. #include <proto/iffparse.h>
  10.  
  11. #define MYLIB_GRAPHICS
  12. #include <MyLib.h>
  13.  
  14. #include "SPRT.h"
  15.  
  16. #define SPRTF_NOMASKDATA    (1<<10)
  17.  
  18. /************************************************************************/
  19.  
  20. struct BMHD
  21. {
  22.   UWORD Width, Height;
  23.   WORD Left, Top;
  24.   UBYTE Depth;
  25.   UBYTE Masking;
  26.   UBYTE Compression;
  27.   UBYTE Pad;
  28.   UWORD TransparentColor;
  29.   UBYTE XAspect, YAspect;
  30.   WORD PageWidth, PageHeight;
  31. };
  32.  
  33. /************************************************************************/
  34.  
  35. struct Sprite
  36. {
  37.   struct BitMap Bitmap;
  38.   WORD Width, Height;
  39.   ULONG OriginalColorCount;
  40.   ULONG *OriginalColorTable;    /* the color table read from the file */
  41.   ULONG ColorCount;
  42.   ULONG *ColorTable;        /* our optimized color table */
  43. };
  44.  
  45. struct OriginalSprite
  46. {
  47.   struct OriginalSprite *Next;
  48.   UWORD Flags;
  49.  
  50.   UWORD Number;
  51.   char *Label;
  52.  
  53.   char *Filename;        /* from the sprite description file */
  54.   ULONG Width;            /* 0 -> anything is allowed */
  55.   ULONG Height;
  56.  
  57.   struct Sprite *Sprite;
  58. };
  59.  
  60. struct ReflectedSprite
  61. {
  62.   struct ReflectedSprite *Next;
  63.   UWORD Flags;
  64.  
  65.   UWORD Number;
  66.   char *Label;
  67.  
  68.   union
  69.     {
  70.       char *Label;
  71.       void *Original;
  72.     } Source;
  73. };
  74.  
  75. /************************************************************************/
  76.  
  77. struct Library *IFFParseBase;
  78. struct GfxBase *GfxBase;
  79. struct DosLibrary *DOSBase;
  80. struct UtilityBase *UtilityBase;
  81.  
  82. static void *MemoryPool;
  83. static void *ChipPool;
  84.  
  85. static char *FilePattern;
  86. static char *LabelPattern;
  87.  
  88. static struct OriginalSprite *OriginalSprites;
  89. static struct ReflectedSprite *ReflectedSprites;
  90.  
  91. static ULONG TotalColorCount;
  92. static ULONG *TotalColorMap;
  93.  
  94. /************************************************************************/
  95. /*                                    */
  96. /* Memory allocation                            */
  97. /*                                    */
  98. /************************************************************************/
  99.  
  100. static void *Malloc(ULONG Size)
  101.  
  102. {
  103.   ULONG *Memory;
  104.  
  105.   if (!(Memory=AllocPooled(MemoryPool,Size)))
  106.     {
  107.       PError(0,NULL);
  108.     }
  109.   return Memory;
  110. }
  111.  
  112. /************************************************************************/
  113. /*                                    */
  114. /* Allocate a bitplane                            */
  115. /*                                    */
  116. /************************************************************************/
  117.  
  118. static PLANEPTR AllocBitplane(struct BitMap *Bitmap)
  119.  
  120. {
  121.   PLANEPTR Plane;
  122.  
  123.   if (!(Plane=AllocPooled(ChipPool,Bitmap->Rows*Bitmap->BytesPerRow)))
  124.     {
  125.       PError(0,NULL);
  126.     }
  127.   return Plane;
  128. }
  129.  
  130. /************************************************************************/
  131. /*                                    */
  132. /* Write the IFF sprite file                        */
  133. /*                                    */
  134. /************************************************************************/
  135.  
  136. static INLINE int WriteSprites(const char *Filename)
  137.  
  138. {
  139.   struct IFFHandle *IFFHandle;
  140.   int RC;
  141.  
  142.   RC=FALSE;
  143.   if ((IFFHandle=AllocIFF()))
  144.     {
  145.       if ((IFFHandle->iff_Stream=Open(Filename,MODE_NEWFILE)))
  146.     {
  147.       LONG ErrorCode;
  148.  
  149.       InitIFFasDOS(IFFHandle);
  150.       if (!(ErrorCode=OpenIFF(IFFHandle,IFFF_WRITE)))
  151.         {
  152.           struct OriginalSprite *Original;
  153.  
  154.           RC=TRUE;
  155.           if (!(ErrorCode=PushChunk(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('F','O','R','M'),IFFSIZE_UNKNOWN)) &&
  156.           !(ErrorCode=PushChunk(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('S','P','R','T'),IFFSIZE_UNKNOWN)))
  157.         {
  158.           ULONG SpriteNumber;
  159.  
  160.           for (SpriteNumber=0; !ErrorCode; SpriteNumber++)
  161.             {
  162.               struct OriginalSprite *Original;
  163.               ULONG OriginalNumber;
  164.  
  165.               for (Original=OriginalSprites, OriginalNumber=0;
  166.                Original && Original->Number!=SpriteNumber;
  167.                Original=Original->Next, OriginalNumber++)
  168.             ;
  169.               if (Original)
  170.             {
  171.               struct SPRT Data;
  172.  
  173.               Data.Original=OriginalNumber;
  174.               Data.Flags=Original->Flags;
  175.               ErrorCode=WriteChunkBytes(IFFHandle,&Data,sizeof(Data));
  176.               if (ErrorCode==sizeof(Data))
  177.                 {
  178.                   ErrorCode=0;
  179.                 }
  180.               else if (ErrorCode>=0)
  181.                 {
  182.                   ErrorCode=IFFERR_WRITE;
  183.                 }
  184.             }
  185.               else
  186.             {
  187.               struct ReflectedSprite *Reflected;
  188.  
  189.               for (Reflected=ReflectedSprites;
  190.                    Reflected && Reflected->Number!=SpriteNumber;
  191.                    Reflected=Reflected->Next)
  192.                 ;
  193.               if (Reflected)
  194.                 {
  195.                   struct SPRT Data;
  196.  
  197.                   Data.Original=((struct OriginalSprite *)(Reflected->Source.Original))->Number;
  198.                   Data.Flags=Reflected->Flags;
  199.                   ErrorCode=WriteChunkBytes(IFFHandle,&Data,sizeof(Data));
  200.                   if (ErrorCode==sizeof(Data))
  201.                 {
  202.                   ErrorCode=0;
  203.                 }
  204.                   else if (ErrorCode>=0)
  205.                 {
  206.                   ErrorCode=IFFERR_WRITE;
  207.                 }
  208.                 }
  209.               else
  210.                 {
  211.                   break;
  212.                 }
  213.             }
  214.             }
  215.           if (!ErrorCode &&
  216.               !(ErrorCode=PopChunk(IFFHandle)) &&    /* SPRT */
  217.               !(ErrorCode=PushChunk(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('C','M','A','P'),3*TotalColorCount)))
  218.             {
  219.               {
  220.             ULONG i;
  221.  
  222.             for (i=0; !ErrorCode && i<TotalColorCount; i++)
  223.               {
  224.                 ErrorCode=WriteChunkBytes(IFFHandle,((UBYTE *)&TotalColorMap[i])+1,3);
  225.                 if (ErrorCode==3)
  226.                   {
  227.                 ErrorCode=0;
  228.                   }
  229.                 else if (ErrorCode>=0)
  230.                   {
  231.                 ErrorCode=IFFERR_WRITE;
  232.                   }
  233.               }
  234.               }
  235.               if (!ErrorCode &&
  236.               !(ErrorCode=PopChunk(IFFHandle)))    /* CMAP */
  237.             {
  238.               for (Original=OriginalSprites; !ErrorCode && Original; Original=Original->Next)
  239.                 {
  240.                   if (!(ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('F','O','R','M'),IFFSIZE_UNKNOWN)) &&
  241.                   !(ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','M','H','D'),sizeof(struct BMHD))))
  242.                 {
  243.                   struct BMHD BMHD;
  244.  
  245.                   BMHD.Width=Original->Sprite->Width;
  246.                   BMHD.Height=Original->Sprite->Height;
  247.                   BMHD.Left=0;
  248.                   BMHD.Top=0;
  249.                   for (BMHD.Depth=1; (1<<BMHD.Depth)<Original->Sprite->ColorCount; BMHD.Depth++)
  250.                     ;
  251.                   BMHD.Masking=(Original->Flags & SPRTF_NOMASK) ? 0 : 2;
  252.                   BMHD.Compression=0;
  253.                   BMHD.Pad=0;
  254.                   BMHD.TransparentColor=0;
  255.                   BMHD.XAspect=1;
  256.                   BMHD.YAspect=1;
  257.                   BMHD.PageWidth=Original->Sprite->Bitmap.BytesPerRow*8;
  258.                   BMHD.PageHeight=Original->Sprite->Bitmap.Rows;
  259.                   ErrorCode=WriteChunkBytes(IFFHandle,&BMHD,sizeof(BMHD));
  260.                   if (ErrorCode==sizeof(BMHD))
  261.                     {
  262.                       if (!(ErrorCode=PopChunk(IFFHandle)))    /* BMHD */
  263.                     {
  264.                       if (Original->Sprite->ColorCount)
  265.                         {
  266.                           if (!(ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('C','M','A','P'),Original->Sprite->ColorCount*3)))
  267.                         {
  268.                           ULONG i;
  269.  
  270.                           for (i=0; !ErrorCode && i<Original->Sprite->ColorCount; i++)
  271.                             {
  272.                               ErrorCode=WriteChunkBytes(IFFHandle,((UBYTE *)&Original->Sprite->ColorTable[i])+1,3);
  273.                               if (ErrorCode==3)
  274.                             {
  275.                               ErrorCode=0;
  276.                             }
  277.                               else if (ErrorCode>=0)
  278.                             {
  279.                               ErrorCode=IFFERR_WRITE;
  280.                             }
  281.                             }
  282.                           if (!ErrorCode)
  283.                             ErrorCode=PopChunk(IFFHandle);    /* CMAP */
  284.                         }
  285.                         }
  286.                       if (!ErrorCode &&
  287.                           !(ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','O','D','Y'),Original->Sprite->Bitmap.Rows*Original->Sprite->Bitmap.BytesPerRow*BMHD.Depth)))
  288.                         {
  289.                           WORD Row;
  290.  
  291.                           for (Row=0; !ErrorCode && Row<Original->Sprite->Bitmap.Rows; Row++)
  292.                         {
  293.                           WORD Plane;
  294.  
  295.                           for (Plane=0; !ErrorCode && Plane<BMHD.Depth; Plane++)
  296.                             {
  297.                               ErrorCode=WriteChunkBytes(IFFHandle,((UBYTE *)Original->Sprite->Bitmap.Planes[Plane])+Row*Original->Sprite->Bitmap.BytesPerRow,Original->Sprite->Bitmap.BytesPerRow);
  298.                               if (ErrorCode==Original->Sprite->Bitmap.BytesPerRow)
  299.                             {
  300.                               ErrorCode=0;
  301.                             }
  302.                               else if (ErrorCode>=0)
  303.                             {
  304.                               ErrorCode=IFFERR_WRITE;
  305.                             }
  306.                             }
  307.                         }
  308.                           if (!ErrorCode && !(ErrorCode=PopChunk(IFFHandle)))    /* BODY */
  309.                         {
  310.                           ErrorCode=PopChunk(IFFHandle);    /* ILBM */
  311.                         }
  312.                         }
  313.                     }
  314.                     }
  315.                   else if (ErrorCode>=0)
  316.                     {
  317.                       ErrorCode=IFFERR_WRITE;
  318.                     }
  319.                 }
  320.                 }
  321.             }
  322.             }
  323.           if (!ErrorCode)
  324.             {
  325.               ErrorCode=PopChunk(IFFHandle);    /* SPRT */
  326.             }
  327.         }
  328.           CloseIFF(IFFHandle);
  329.         }
  330.       if (ErrorCode)
  331.         {
  332.           VFPrintf(StdErr,"IFF error %ld\n",&ErrorCode);
  333.           RC=FALSE;
  334.         }
  335.       if (!Close(IFFHandle->iff_Stream))
  336.         {
  337.           PError(0,Filename);
  338.           RC=FALSE;
  339.         }
  340.       if (RC)
  341.         {
  342.           SetProtection(Filename,FIBF_EXECUTE);
  343.         }
  344.       else
  345.         {
  346.           DeleteFile(Filename);
  347.         }
  348.     }
  349.       else
  350.     {
  351.       PError(0,Filename);
  352.     }
  353.       FreeIFF(IFFHandle);
  354.     }
  355.   return RC;
  356. }
  357.  
  358. /************************************************************************/
  359. /*                                    */
  360. /* Make a colormap of ALL colors                    */
  361. /*                                    */
  362. /************************************************************************/
  363.  
  364. static INLINE int MakeColormap(void)
  365.  
  366. {
  367.   struct OriginalSprite *Original;
  368.  
  369.   for (Original=OriginalSprites; Original; Original=Original->Next)
  370.     {
  371.       TotalColorCount+=Original->Sprite->ColorCount;
  372.     }
  373.   if (!(TotalColorMap=Malloc(TotalColorCount*sizeof(*TotalColorMap))))
  374.     {
  375.       return FALSE;
  376.     }
  377.   TotalColorCount=0;
  378.   for (Original=OriginalSprites; Original; Original=Original->Next)
  379.     {
  380.       ULONG Color;
  381.  
  382.       for (Color=(Original->Flags & SPRTF_NOMASK) ? 0 : 1; Color<Original->Sprite->ColorCount; Color++)
  383.     {
  384.       ULONG i;
  385.  
  386.       for (i=0;
  387.            i<TotalColorCount && (TotalColorMap[i]<Original->Sprite->ColorTable[Color]);
  388.            i++)
  389.         ;
  390.       if (i==TotalColorCount || TotalColorMap[i]!=Original->Sprite->ColorTable[Color])
  391.         {
  392.           ULONG j;
  393.  
  394.           for (j=TotalColorCount; j>i; j--)
  395.         {
  396.           TotalColorMap[j]=TotalColorMap[j-1];
  397.         }
  398.           TotalColorMap[i]=Original->Sprite->ColorTable[Color];
  399.           TotalColorCount++;
  400.         }
  401.     }
  402.     }
  403.   return TRUE;
  404. }
  405.  
  406. /************************************************************************/
  407. /*                                    */
  408. /* Remap the sprite to the new colortable                */
  409. /*                                    */
  410. /************************************************************************/
  411.  
  412. static INLINE void RemapColors(struct OriginalSprite *OriginalSprite)
  413.  
  414. {
  415.   struct Sprite *Sprite;
  416.  
  417.   Sprite=OriginalSprite->Sprite;
  418.   if (Sprite->ColorCount)
  419.     {
  420.       struct RastPort RastPort;
  421.       WORD y;
  422.  
  423.       if ((OriginalSprite->Flags & SPRTF_NOMASK) && !(OriginalSprite->Flags & SPRTF_NOMASKDATA))
  424.     {
  425.       Sprite->ColorTable[0]=Sprite->ColorTable[--Sprite->ColorCount];
  426.     }
  427.       if (OriginalSprite->Flags & SPRTF_NOIMAGE)
  428.     {
  429.       Sprite->ColorCount=0;
  430.     }
  431.       InitRastPort(&RastPort);
  432.       RastPort.BitMap=&Sprite->Bitmap;
  433.       for (y=0; y<Sprite->Height; y++)
  434.     {
  435.       WORD x;
  436.  
  437.       for (x=0; x<Sprite->Width; x++)
  438.         {
  439.           ULONG Pixel;
  440.           ULONG NewPixel;
  441.  
  442.           Pixel=ReadPixel(&RastPort,x,y);
  443.           if ((OriginalSprite->Flags & SPRTF_NOMASKDATA) || Pixel)
  444.         {
  445.           if (OriginalSprite->Flags & SPRTF_NOIMAGE)
  446.             {
  447.               NewPixel=1;
  448.             }
  449.           else
  450.             {
  451.               for (NewPixel=(OriginalSprite->Flags & SPRTF_NOMASK) ? 0 : 1;
  452.                Sprite->ColorTable[NewPixel]!=Sprite->OriginalColorTable[Pixel];
  453.                NewPixel++)
  454.             ;
  455.               assert(NewPixel<Sprite->ColorCount);
  456.             }
  457.         }
  458.           else
  459.         {
  460.           NewPixel=0;
  461.         }
  462.           SetABPenDrMd(&RastPort,NewPixel,NewPixel,JAM1);
  463.           WritePixel(&RastPort,x,y);
  464.         }
  465.     }
  466.       
  467.       if (!(OriginalSprite->Flags & SPRTF_NOMASK))
  468.     {
  469.       Sprite->ColorTable[0]=Sprite->ColorTable[1];
  470.     }
  471.     }
  472. }
  473.  
  474. /************************************************************************/
  475. /*                                    */
  476. /* Make sure we don't load the same sprite file twice            */
  477. /*                                    */
  478. /************************************************************************/
  479.  
  480. static INLINE int RemoveDoubleFiles(void)
  481.  
  482. {
  483.   struct OriginalSprite **Original;
  484.  
  485.   for (Original=&OriginalSprites; *Original; Original=&(*Original)->Next)
  486.     {
  487.       struct OriginalSprite **Sprite;
  488.  
  489.       for (Sprite=&(*Original)->Next; *Sprite; Sprite=&(*Sprite)->Next)
  490.     {
  491.       if (!strcmp((*Original)->Filename,(*Sprite)->Filename))
  492.         {
  493.           if ((*Sprite)->Width==(*Original)->Width && (*Sprite)->Height==(*Original)->Height)
  494.         {
  495.           struct ReflectedSprite *Reflected;
  496.  
  497.           if ((Reflected=Malloc(sizeof(*Reflected))))
  498.             {
  499.               Reflected->Flags=SPRTF_ORIGINAL;
  500.               Reflected->Label=(*Sprite)->Label;
  501.               Reflected->Source.Original=*Original;
  502.               Reflected->Next=ReflectedSprites;
  503.               ReflectedSprites=Reflected;
  504.               *Original=(*Original)->Next;
  505.             }
  506.           else
  507.             {
  508.               return FALSE;
  509.             }
  510.         }
  511.           else
  512.         {
  513.           VFPrintf(StdErr,"Mismatched width/height for \x22%s\x22\n",&(*Original)->Filename);
  514.           return FALSE;
  515.         }
  516.         }
  517.     }
  518.     }
  519.   return TRUE;
  520. }
  521.  
  522. /************************************************************************/
  523. /*                                    */
  524. /* Make the graph                            */
  525. /*                                    */
  526. /************************************************************************/
  527.  
  528. static INLINE int MakeGraph(void)
  529.  
  530. {
  531.   struct ReflectedSprite *ReflectedSprite;
  532.   int RC;
  533.  
  534.   RC=TRUE;
  535.   for (ReflectedSprite=ReflectedSprites; ReflectedSprite; ReflectedSprite=ReflectedSprite->Next)
  536.     {
  537.       struct OriginalSprite *Original;
  538.  
  539.       for (Original=OriginalSprites;
  540.        Original && (!Original->Label || strcmp(ReflectedSprite->Source.Label,Original->Label));
  541.        Original=Original->Next)
  542.     ;
  543.       if (Original)
  544.     {
  545.       ReflectedSprite->Source.Original=Original;
  546.     }
  547.       else
  548.     {
  549.       struct ReflectedSprite *Reflected;
  550.  
  551.       for (Reflected=ReflectedSprites;
  552.            Reflected && (!Reflected->Label || strcmp(ReflectedSprite->Source.Label,Reflected->Label));
  553.            Reflected=Reflected->Next)
  554.         ;
  555.       if (Reflected)
  556.         {
  557.           ReflectedSprite->Source.Original=Reflected;
  558.         }
  559.       else
  560.         {
  561.           VFPrintf(StdErr,"Label \x22%s\x22 not found\n",&ReflectedSprite->Source.Label);
  562.           RC=FALSE;
  563.         }
  564.     }
  565.     }
  566.   return RC;
  567. }
  568.  
  569. /************************************************************************/
  570. /*                                    */
  571. /* Remove double colors from colortable                    */
  572. /*                                    */
  573. /************************************************************************/
  574.  
  575. static INLINE void RemoveDoubleColors(struct OriginalSprite *OriginalSprite)
  576.  
  577. {
  578.   struct Sprite *Sprite;
  579.   ULONG i;
  580.  
  581.   Sprite=OriginalSprite->Sprite;
  582.   for (i=(OriginalSprite->Flags & SPRTF_NOMASKDATA) ? 1 : 2; i<Sprite->ColorCount; i++)
  583.     {
  584.       if (Sprite->ColorTable[i-1]==Sprite->ColorTable[i])
  585.     {
  586.       ULONG j;
  587.  
  588.       Sprite->ColorCount--;
  589.       for (j=i; j<Sprite->ColorCount; j++)
  590.         {
  591.           Sprite->ColorTable[j]=Sprite->ColorTable[j+1];
  592.         }
  593.       i--;
  594.     }
  595.     }
  596. }
  597.  
  598. /************************************************************************/
  599. /*                                    */
  600. /* Sort the colortable                            */
  601. /*                                    */
  602. /************************************************************************/
  603.  
  604. static INLINE void SortColors(struct OriginalSprite *OriginalSprite)
  605.  
  606. {
  607.   struct Sprite *Sprite;
  608.   ULONG i;
  609.  
  610.   Sprite=OriginalSprite->Sprite;
  611.   for (i=(OriginalSprite->Flags & SPRTF_NOMASKDATA) ? 0 : 1; i<Sprite->ColorCount; i++)
  612.     {
  613.       ULONG j;
  614.  
  615.       for (j=i+1; j<Sprite->ColorCount; j++)
  616.     {
  617.       if (Sprite->ColorTable[i]>Sprite->ColorTable[j])
  618.         {
  619.           ULONG h;
  620.  
  621.           h=Sprite->ColorTable[i];
  622.           Sprite->ColorTable[i]=Sprite->ColorTable[j];
  623.           Sprite->ColorTable[j]=h;
  624.         }
  625.     }
  626.     }
  627. }
  628.  
  629. /************************************************************************/
  630. /*                                    */
  631. /* Remove unused colors.                        */
  632. /* This must be called before any of the other optimization functions.    */
  633. /*                                    */
  634. /* Does some integrity checks, too.                    */
  635. /*                                    */
  636. /************************************************************************/
  637.  
  638. static INLINE int RemoveUnusedColors(struct OriginalSprite *OriginalSprite)
  639.  
  640. {
  641.   struct Sprite *Sprite;
  642.  
  643.   Sprite=OriginalSprite->Sprite;
  644.   if (Sprite->ColorCount)
  645.     {
  646.       struct RastPort RastPort;
  647.       ULONG i;
  648.       WORD y;
  649.  
  650.       InitRastPort(&RastPort);
  651.       RastPort.BitMap=&Sprite->Bitmap;
  652.       for (y=0; y<Sprite->Height; y++)
  653.     {
  654.       WORD x;
  655.  
  656.       for (x=0; x<Sprite->Width; x++)
  657.         {
  658.           ULONG Pixel;
  659.  
  660.           Pixel=ReadPixel(&RastPort,x,y);
  661.           if (Pixel>Sprite->ColorCount)
  662.         {
  663.           VFPrintf(StdErr,"Used color not defined in colortable\n",NULL);
  664.           return FALSE;
  665.         }
  666.           Sprite->ColorTable[Pixel]|=1<<31;
  667.         }
  668.     }
  669.       for (i=(OriginalSprite->Flags & SPRTF_NOMASKDATA) ? 0 : 1; i<Sprite->ColorCount; i++)
  670.     {
  671.       if (!(Sprite->ColorTable[i]&(1<<31)))
  672.         {
  673.           Sprite->ColorTable[i]=Sprite->ColorTable[--Sprite->ColorCount];
  674.           i--;
  675.         }
  676.       else
  677.         {
  678.           Sprite->ColorTable[i]&=~(1<<31);
  679.         }
  680.     }
  681.     }
  682.   return TRUE;
  683. }
  684.  
  685. /************************************************************************/
  686. /*                                    */
  687. /* Read an IFF-ILBM image and return it                    */
  688. /*                                    */
  689. /************************************************************************/
  690.  
  691. static INLINE struct Sprite *ReadSprite(struct OriginalSprite *OriginalSprite, const char *Name)
  692.  
  693. {
  694.   struct Sprite *Sprite;
  695.   struct IFFHandle *IFFHandle;
  696.  
  697.   Sprite=NULL;
  698.   if ((IFFHandle=AllocIFF()))
  699.     {
  700.       if ((IFFHandle->iff_Stream=Open(Name,MODE_OLDFILE)))
  701.     {
  702.       LONG ErrorCode;
  703.  
  704.       InitIFFasDOS(IFFHandle);
  705.       if (!(ErrorCode=OpenIFF(IFFHandle,IFFF_READ)))
  706.         {
  707.           static ULONG PropArray[][2]=
  708.         {
  709.           {MAKE_ID('I','L','B','M'),MAKE_ID('B','M','H','D')},
  710.           {MAKE_ID('I','L','B','M'),MAKE_ID('C','M','A','P')}
  711.         };
  712.  
  713.           if (!(ErrorCode=PropChunks(IFFHandle,(ULONG *)PropArray,ARRAYSIZE(PropArray))))
  714.         {
  715.           if (!(ErrorCode=StopChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','O','D','Y'))))
  716.             {
  717.               if (!(ErrorCode=ParseIFF(IFFHandle,IFFPARSE_SCAN)))
  718.             {
  719.               struct StoredProperty *BMHDProperty;
  720.  
  721.               BMHDProperty=FindProp(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','M','H','D'));
  722.               if (BMHDProperty)
  723.                 {
  724.                   ULONG ColorCount;
  725.                   struct StoredProperty *CMAPProperty;
  726.                   WORD Depth;
  727.  
  728.                   CMAPProperty=FindProp(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('C','M','A','P'));
  729.                   if (CMAPProperty)
  730.                 {
  731.                   if (OriginalSprite->Flags & SPRTF_NOIMAGE)
  732.                     {
  733.                       ColorCount=0;
  734.                       CMAPProperty=NULL;
  735.                     }
  736.                   else
  737.                     {
  738.                       ColorCount=CMAPProperty->sp_Size/3;
  739.                     }
  740.                 }
  741.                   else
  742.                 {
  743.                   ColorCount=0;
  744.                   OriginalSprite->Flags|=SPRTF_NOIMAGE;
  745.                 }
  746.                   Depth=((struct BMHD *)BMHDProperty->sp_Data)->Depth;
  747.                   switch (((struct BMHD *)BMHDProperty->sp_Data)->Masking)
  748.                 {
  749.                 case 0:
  750.                   OriginalSprite->Flags|=SPRTF_NOMASKDATA | SPRTF_NOMASK;
  751.                   break;
  752.  
  753.                 case 1:
  754.                   Depth++;
  755.                   break;
  756.  
  757.                 case 2:
  758.                   break;
  759.  
  760.                 default:
  761.                   VFPrintf(StdErr,"Masking method not supported\n",NULL);
  762.                   break;
  763.                 }
  764.                   if (Depth<=8)
  765.                 {
  766.                   if ((Sprite=Malloc(sizeof(*Sprite)+(2*(ColorCount+1))*sizeof(ULONG))))
  767.                     {
  768.                       {
  769.                     WORD Plane;
  770.  
  771.                     for (Plane=0; Plane<8; Plane++)
  772.                       {
  773.                         Sprite->Bitmap.Planes[Plane]=NULL;
  774.                       }
  775.                       }
  776.                       Sprite->OriginalColorCount=ColorCount;
  777.                       Sprite->ColorCount=ColorCount;
  778.                       Sprite->Width=((struct BMHD *)BMHDProperty->sp_Data)->Width;
  779.                       Sprite->Height=((struct BMHD *)BMHDProperty->sp_Data)->Height;
  780.                       Sprite->OriginalColorTable=(ULONG *)(Sprite+1);
  781.                       Sprite->ColorTable=Sprite->OriginalColorTable+ColorCount+1;
  782.                       InitBitMap(&Sprite->Bitmap, Depth, Sprite->Width, Sprite->Height);
  783.  
  784.                       {
  785.                     WORD Plane;
  786.  
  787.                     for (Plane=0; Sprite && Plane<Depth; Plane++)
  788.                       {
  789.                         if (!(Sprite->Bitmap.Planes[Plane]=AllocBitplane(&Sprite->Bitmap)))
  790.                           {
  791.                         Sprite=NULL;
  792.                           }
  793.                       }
  794.                       }
  795.  
  796.                       /* copy the color table */
  797.                       if (Sprite && CMAPProperty)
  798.                     {
  799.                       ULONG i;
  800.                       UBYTE *Colors;
  801.  
  802.                       Colors=CMAPProperty->sp_Data;
  803.                       for (i=0; i<ColorCount; i++)
  804.                         {
  805.                           union
  806.                         {
  807.                           struct
  808.                             {
  809.                               UBYTE Pad;
  810.                               UBYTE Red, Green, Blue;
  811.                             } RGB;
  812.                           ULONG Value;
  813.                         } Color;
  814.  
  815.                           Color.RGB.Red=*(Colors++);
  816.                           Color.RGB.Green=*(Colors++);
  817.                           Color.RGB.Blue=*(Colors++);
  818.                           Color.RGB.Pad=0;
  819.                           Sprite->OriginalColorTable[i]=Color.Value;
  820.                           Sprite->ColorTable[i]=Color.Value;
  821.                         }
  822.                     }
  823.  
  824.                       /* Read the image */
  825.                       {
  826.                     WORD Row;
  827.  
  828.                     for (Row=0; Sprite && Row<Sprite->Height; Row++)
  829.                       {
  830.                         WORD Plane;
  831.  
  832.                         for (Plane=0; Plane<Depth; Plane++)
  833.                           {
  834.                         UBYTE *Data;
  835.  
  836.                         Data=(((UBYTE *)Sprite->Bitmap.Planes[Plane])+
  837.                               Row*Sprite->Bitmap.BytesPerRow);
  838.                         switch (((struct BMHD *)BMHDProperty->sp_Data)->Compression)
  839.                           {
  840.                           case 0:
  841.                             {
  842.                               ErrorCode=ReadChunkBytes(IFFHandle,Data,Sprite->Bitmap.BytesPerRow);
  843.                               if (ErrorCode==Sprite->Bitmap.BytesPerRow)
  844.                             {
  845.                               ErrorCode=0;
  846.                             }
  847.                               else
  848.                             {
  849.                               Sprite=NULL;
  850.                             }
  851.                             }
  852.                             break;
  853.  
  854.                           case 1:
  855.                             {
  856.                               UWORD Count;
  857.  
  858.                               Count=0;
  859.                               while (Sprite && Count<Sprite->Bitmap.BytesPerRow)
  860.                             {
  861.                               BYTE n;
  862.  
  863.                               ErrorCode=ReadChunkBytes(IFFHandle,&n,1);
  864.                               if (ErrorCode==1)
  865.                                 {
  866.                                   ErrorCode=0;
  867.                                   if (n>=0)
  868.                                 {
  869.                                   ErrorCode=ReadChunkBytes(IFFHandle,Data+Count,n+1);
  870.                                   if (ErrorCode==n+1)
  871.                                     {
  872.                                       ErrorCode=0;
  873.                                       Count+=n+1;
  874.                                     }
  875.                                   else
  876.                                     {
  877.                                       Sprite=NULL;
  878.                                     }
  879.                                 }
  880.                                   else if (n!=-128)
  881.                                 {
  882.                                   UBYTE Byte;
  883.  
  884.                                   ErrorCode=ReadChunkBytes(IFFHandle,&Byte,1);
  885.                                   if (ErrorCode==1)
  886.                                     {
  887.                                       ErrorCode=0;
  888.                                       for (n=-n; n>=0; n--)
  889.                                     {
  890.                                       Data[Count++]=Byte;
  891.                                     }
  892.                                     }
  893.                                   else
  894.                                     {
  895.                                       Sprite=NULL;
  896.                                     }
  897.                                 }
  898.                                 }
  899.                               else
  900.                                 {
  901.                                   Sprite=NULL;
  902.                                 }
  903.                             }
  904.                             }
  905.                             break;
  906.  
  907.                           default:
  908.                             {
  909.                               VFPrintf(StdErr,"Compression method not supported\n",NULL);
  910.                               Sprite=NULL;
  911.                             }
  912.                             break;
  913.                           }
  914.                           }
  915.                       }
  916.                       }
  917.  
  918.                       if (Sprite)
  919.                     {
  920.                       OriginalSprite->Sprite=Sprite;
  921.  
  922.                       /* change the mask, if necessary */
  923.                       switch(((struct BMHD *)BMHDProperty->sp_Data)->Masking)
  924.                         {
  925.                         case 1:
  926.                           {
  927.                         struct RastPort RastPort;
  928.                         WORD y;
  929.  
  930.                         Sprite->ColorTable[Sprite->ColorCount++]=Sprite->ColorTable[0];
  931.                         Sprite->OriginalColorTable[Sprite->OriginalColorCount++]=Sprite->OriginalColorTable[0];
  932.                         InitRastPort(&RastPort);
  933.                         RastPort.BitMap=&Sprite->Bitmap;
  934.                         for (y=0; y<Sprite->Height; y++)
  935.                           {
  936.                             WORD x;
  937.  
  938.                             for (x=0; x<Sprite->Width; x++)
  939.                               {
  940.                             ULONG Pixel;
  941.  
  942.                             Pixel=ReadPixel(&RastPort,x,y);
  943.                             if (Pixel & (1<<(Sprite->Bitmap.Depth-1)))
  944.                               {
  945.                                 Pixel &=~ (1<<(Sprite->Bitmap.Depth-1));
  946.                                 if (Pixel==0)
  947.                                   {
  948.                                 Pixel=Sprite->ColorCount-1;
  949.                                   }
  950.                               }
  951.                             else
  952.                               {
  953.                                 Pixel=0;
  954.                               }
  955.                             SetABPenDrMd(&RastPort,Pixel,Pixel,JAM1);
  956.                             WritePixel(&RastPort,x,y);
  957.                               }
  958.                           }
  959.                           }
  960.                           break;
  961.  
  962.                         case 2:
  963.                           {
  964.                         ULONG TransparentColor;
  965.  
  966.                         if ((TransparentColor=((struct BMHD *)BMHDProperty->sp_Data)->TransparentColor))
  967.                           {
  968.                             struct RastPort RastPort;
  969.                             WORD y;
  970.  
  971.                             Sprite->ColorTable[TransparentColor]=Sprite->ColorTable[0];
  972.                             Sprite->OriginalColorTable[TransparentColor]=Sprite->OriginalColorTable[0];
  973.                             InitRastPort(&RastPort);
  974.                             RastPort.BitMap=&Sprite->Bitmap;
  975.                             for (y=0; y<Sprite->Height; y++)
  976.                               {
  977.                             WORD x;
  978.  
  979.                             for (x=0; x<Sprite->Width; x++)
  980.                               {
  981.                                 ULONG Pixel;
  982.  
  983.                                 Pixel=ReadPixel(&RastPort,x,y);
  984.                                 if (Pixel==TransparentColor)
  985.                                   {
  986.                                 SetABPenDrMd(&RastPort,0,0,JAM1);
  987.                                 WritePixel(&RastPort,x,y);
  988.                                   }
  989.                                 else if (Pixel==0)
  990.                                   {
  991.                                 SetABPenDrMd(&RastPort,
  992.                                          TransparentColor,
  993.                                          TransparentColor,
  994.                                          JAM1);
  995.                                 WritePixel(&RastPort,x,y);
  996.                                   }
  997.                               }
  998.                               }
  999.                           }
  1000.                           }
  1001.                           break;
  1002.                         }
  1003.                     }
  1004.                     }
  1005.                 }
  1006.                 }
  1007.             }
  1008.             }
  1009.         }
  1010.           CloseIFF(IFFHandle);
  1011.         }
  1012.       Close(IFFHandle->iff_Stream);
  1013.       if (ErrorCode)
  1014.         {
  1015.           VFPrintf(StdErr,"IFF error: %ld\n",&ErrorCode);
  1016.         }
  1017.     }
  1018.       else
  1019.     {
  1020.       PError(0,Name);
  1021.     }
  1022.       FreeIFF(IFFHandle);
  1023.     }
  1024.   return Sprite;
  1025. }
  1026.  
  1027. /************************************************************************/
  1028. /*                                    */
  1029. /* Read the sprite files                        */
  1030. /*                                    */
  1031. /************************************************************************/
  1032.  
  1033. static INLINE int ReadSprites(void)
  1034.  
  1035. {
  1036.   struct OriginalSprite *Original;
  1037.  
  1038.   for (Original=OriginalSprites; Original; Original=Original->Next)
  1039.     {
  1040.       char Filename[1024];
  1041.       struct Sprite *Sprite;
  1042.  
  1043.       SPrintf(Filename,FilePattern,Original->Filename);
  1044.       if ((Sprite=ReadSprite(Original,Filename)))
  1045.     {
  1046.       if (Original->Flags & SPRTF_NOIMAGE)
  1047.         {
  1048.         }
  1049.       else
  1050.         {
  1051.           if (RemoveUnusedColors(Original))
  1052.         {
  1053.           SortColors(Original);
  1054.           RemoveDoubleColors(Original);
  1055.           RemapColors(Original);
  1056.         }
  1057.           else
  1058.         {
  1059.           return FALSE;
  1060.         }
  1061.         }
  1062.       Original->Flags&=~SPRTF_NOMASKDATA;
  1063.     }
  1064.       else
  1065.     {
  1066.       return FALSE;
  1067.     }
  1068.       if (CheckSignal(SIGBREAKF_CTRL_C))
  1069.     {
  1070.       PError(ERROR_BREAK,NULL);
  1071.       return FALSE;
  1072.     }
  1073.     }
  1074.   return TRUE;
  1075. }
  1076.  
  1077. /************************************************************************/
  1078. /*                                    */
  1079. /* Output the header file                        */
  1080. /*                                    */
  1081. /************************************************************************/
  1082.  
  1083. static INLINE int CreateHeaderFile(const char *Filename)
  1084.  
  1085. {
  1086.   int RC;
  1087.  
  1088.   RC=FALSE;
  1089.   if (Filename)
  1090.     {
  1091.       BPTR File;
  1092.  
  1093.       if ((File=Open(Filename,MODE_NEWFILE)))
  1094.     {
  1095.       struct DateStamp TheStamp;
  1096.  
  1097.       DateStamp(&TheStamp);
  1098.       if (!FPuts(File,
  1099.              "/* This file was created automatically.    */\n"
  1100.              "/* Do not edit.                */\n\n") &&
  1101.           VFPrintf(File,"#ifndef SPRITE_%lu_%lu_%lu\n",&TheStamp)!=-1 &&
  1102.           VFPrintf(File,"#define SPRITE_%lu_%lu_%lu\n\n",&TheStamp)!=-1)
  1103.         {
  1104.           RC=TRUE;
  1105.           {
  1106.         struct OriginalSprite *Original;
  1107.  
  1108.         for (Original=OriginalSprites; RC && Original; Original=Original->Next)
  1109.           {
  1110.             if (Original->Label && Original->Label[0] && Original->Label[0]!='_')
  1111.               {
  1112.             if (FPuts(File,"#define ") ||
  1113.                 VFPrintf(File,LabelPattern,&Original->Label)==-1 ||
  1114.                 VFPrintf(File," %u\n",&Original->Number)==-1)
  1115.               {
  1116.                 RC=FALSE;
  1117.               }
  1118.               }
  1119.           }
  1120.           }
  1121.           {
  1122.         struct ReflectedSprite *Reflected;
  1123.  
  1124.         for (Reflected=ReflectedSprites; RC && Reflected; Reflected=Reflected->Next)
  1125.           {
  1126.             if (Reflected->Label && Reflected->Label[0] && Reflected->Label[0]!='_')
  1127.               {
  1128.             if (FPuts(File,"#define ") ||
  1129.                 VFPrintf(File,LabelPattern,&Reflected->Label)==-1 ||
  1130.                 VFPrintf(File," %u\n",&Reflected->Number)==-1)
  1131.               {
  1132.                 RC=FALSE;
  1133.               }
  1134.               }
  1135.           }
  1136.           }
  1137.           if (RC)
  1138.         {
  1139.           if (VFPrintf(File,"\n#endif  /* SPRITE_%lu_%lu_%lu */\n",&TheStamp)==-1)
  1140.             {
  1141.               RC=FALSE;
  1142.             }
  1143.         }
  1144.           if (!RC)
  1145.         {
  1146.           PError(0,Filename);
  1147.         }
  1148.         }
  1149.       if (!Close(File) && RC)
  1150.         {
  1151.           PError(0,Filename);
  1152.           RC=FALSE;
  1153.         }
  1154.       if (!RC)
  1155.         {
  1156.           DeleteFile(Filename);
  1157.         }
  1158.       else
  1159.         {
  1160.           SetProtection(Filename,FIBF_EXECUTE);
  1161.         }
  1162.     }
  1163.       else
  1164.     {
  1165.       PError(0,Filename);
  1166.     }
  1167.     }
  1168.   else
  1169.     {
  1170.       RC=TRUE;
  1171.     }
  1172.   return RC;
  1173. }
  1174.  
  1175. /************************************************************************/
  1176. /*                                    */
  1177. /* Read the sprite description file                    */
  1178. /*                                    */
  1179. /* The following line formats are allowed:                */
  1180. /* empty line                                */
  1181. /* # comment line                            */
  1182. /* FILEPATTERN/K,LABELPATTERN/K                        */
  1183. /* FILE/A,WIDTH/N,HEIGHT/N,NOIMAGE/S,NOMASK/S,LABEL/K            */
  1184. /* REFLECT/K,DIAGONAL/S,VERTICAL/S,HORIZONTAL/S,ALIAS/S,COPY/S,LABEL/K    */
  1185. /*                                    */
  1186. /************************************************************************/
  1187.  
  1188. static INLINE int ReadSpriteDesc(const char *Name)
  1189.  
  1190. {
  1191.   BPTR Filehandle;
  1192.   int RC;
  1193.  
  1194.   RC=FALSE;
  1195.   if ((Filehandle=Open(Name,MODE_OLDFILE)))
  1196.     {
  1197.       ULONG SpriteNumber;
  1198.       LONG c;
  1199.  
  1200.       SpriteNumber=0;
  1201.       do
  1202.     {
  1203.       /* skip whitespace */
  1204.       do
  1205.         {
  1206.           c=FGetC(Filehandle);
  1207.         }
  1208.       while (c==' ' || c=='\t' || c=='\n');
  1209.  
  1210.       /* comment? */
  1211.       if (c=='#')
  1212.         {
  1213.           do
  1214.         {
  1215.           c=FGetC(Filehandle);
  1216.         }
  1217.           while (c!='\n' && c!=-1);
  1218.         }
  1219.       else if (c!=-1)
  1220.         {
  1221.           LONG FilePos;
  1222.  
  1223.           UnGetC(Filehandle,c);
  1224.           c=FilePos=Seek(Filehandle,0,OFFSET_CURRENT);
  1225.  
  1226.           if (c!=-1)
  1227.         {
  1228.           BPTR OldInput;
  1229.           struct RDArgs *RDArgs;
  1230.           union
  1231.             {
  1232.               struct
  1233.             {
  1234.               char *FilePattern;
  1235.               char *LabelPattern;
  1236.             } Type1;
  1237.               struct
  1238.             {
  1239.               char *Source;
  1240.               LONG Alias;
  1241.               LONG Vertical;
  1242.               LONG Horizontal;
  1243.               LONG Diagonal;
  1244.               LONG Copy;
  1245.               char *Label;
  1246.             } Type2;
  1247.               struct
  1248.             {
  1249.               char *Filename;
  1250.               LONG *Width;
  1251.               LONG *Height;
  1252.               LONG NoImage;
  1253.               LONG NoMask;
  1254.               char *Label;
  1255.             } Type3;
  1256.             } Arguments;
  1257.  
  1258.           OldInput=SelectInput(Filehandle);
  1259.           if ((RDArgs=ReadArgs("FILEPATTERN/K/A,LABELPATTERN/K/A",(LONG *)&Arguments.Type1,NULL)))
  1260.             {
  1261.               if (!FilePattern)
  1262.             {
  1263.               if ((FilePattern=Malloc(strlen(Arguments.Type1.FilePattern)+1)))
  1264.                 {
  1265.                   strcpy(FilePattern,Arguments.Type1.FilePattern);
  1266.                   if ((LabelPattern=Malloc(strlen(Arguments.Type1.LabelPattern)+1)))
  1267.                 {
  1268.                   strcpy(LabelPattern,Arguments.Type1.LabelPattern);
  1269.                 }
  1270.                   else
  1271.                 {
  1272.                   c=-1;
  1273.                 }
  1274.                 }
  1275.               else
  1276.                 {
  1277.                   c=-1;
  1278.                 }
  1279.             }
  1280.               else
  1281.             {
  1282.               VFPrintf(StdErr,"Only one FILEPATTERN/LABELPATTERN line allowed\n",NULL);
  1283.               c=-1;
  1284.             }
  1285.             }
  1286.           else
  1287.             {
  1288.               c=Seek(Filehandle,FilePos,OFFSET_BEGINNING);
  1289.               if (c!=-1)
  1290.             {
  1291.               Arguments.Type2.Vertical=Arguments.Type2.Horizontal=Arguments.Type2.Diagonal=Arguments.Type2.Copy=FALSE;
  1292.               Arguments.Type2.Label=NULL;
  1293.               if ((RDArgs=ReadArgs("REFLECT/K/A,ALIAS/S,VERTICAL/S,HORIZONTAL/S,"
  1294.                            "DIAGONAL/S,COPY/S,LABEL/K",(LONG *)&Arguments.Type2,NULL)))
  1295.                 {
  1296.                   struct ReflectedSprite *ReflectedSprite;
  1297.  
  1298.                   if ((ReflectedSprite=Malloc(sizeof(*ReflectedSprite)+strlen(Arguments.Type2.Source)+1)))
  1299.                 {
  1300.                   int Count;
  1301.  
  1302.                   ReflectedSprite->Flags=0;
  1303.                   ReflectedSprite->Number=SpriteNumber++;
  1304.                   ReflectedSprite->Source.Label=(char *)(ReflectedSprite+1);
  1305.                   strcpy(ReflectedSprite->Source.Label,Arguments.Type2.Source);
  1306.                   Count=0;
  1307.                   if (Arguments.Type2.Vertical)
  1308.                     {
  1309.                       ReflectedSprite->Flags|=SPRTF_VERTICAL;
  1310.                       Count++;
  1311.                     }
  1312.                   if (Arguments.Type2.Horizontal)
  1313.                     {
  1314.                       ReflectedSprite->Flags|=SPRTF_HORIZONTAL;
  1315.                       Count++;
  1316.                     }
  1317.                   if (Arguments.Type2.Diagonal)
  1318.                     {
  1319.                       ReflectedSprite->Flags|=SPRTF_VERTICAL | SPRTF_HORIZONTAL;
  1320.                       Count++;
  1321.                     }
  1322.                   if (Arguments.Type2.Copy)
  1323.                     {
  1324.                       ReflectedSprite->Flags|=SPRTF_COPY;
  1325.                       Count++;
  1326.                     }
  1327.                   if (Count<=1)
  1328.                     {
  1329.                       ReflectedSprite->Next=ReflectedSprites;
  1330.                       ReflectedSprites=ReflectedSprite;
  1331.                       if (Arguments.Type2.Label)
  1332.                     {
  1333.                       if ((ReflectedSprite->Label=Malloc(strlen(Arguments.Type2.Label)+1)))
  1334.                         {
  1335.                           strcpy(ReflectedSprite->Label,Arguments.Type2.Label);
  1336.                         }
  1337.                       else
  1338.                         {
  1339.                           c=-1;
  1340.                         }
  1341.                     }
  1342.                       else
  1343.                     {
  1344.                       ReflectedSprite->Label=NULL;
  1345.                     }
  1346.                     }
  1347.                   else
  1348.                     {
  1349.                       VFPrintf(StdErr,"Only one of HORIZONTAL, VERTICAL or DIAGONAL is allowed\n",NULL);
  1350.                       c=-1;
  1351.                     }
  1352.                 }
  1353.                   else
  1354.                 {
  1355.                   c=-1;
  1356.                 }
  1357.                 }
  1358.               else
  1359.                 {
  1360.                   c=Seek(Filehandle,FilePos,OFFSET_BEGINNING);
  1361.                   if (c!=-1)
  1362.                 {
  1363.                   Arguments.Type3.Width=Arguments.Type3.Height=NULL;
  1364.                   Arguments.Type3.Label=NULL;
  1365.                   Arguments.Type3.NoImage=FALSE;
  1366.                   Arguments.Type3.NoMask=FALSE;
  1367.                   if ((RDArgs=ReadArgs("FILENAME/A,WIDTH/N,HEIGHT/N,NOIMAGE=MASKONLY/S,NOMASK=IMAGEONLY/S,LABEL/K",
  1368.                                (LONG *)&Arguments.Type3,NULL)))
  1369.                     {
  1370.                       struct OriginalSprite *OriginalSprite;
  1371.  
  1372.                       if ((Arguments.Type3.Width && !*Arguments.Type3.Width) ||
  1373.                       (Arguments.Type3.Height && !*Arguments.Type3.Height))
  1374.                     {
  1375.                       VFPrintf(StdErr,"Width/Height zero is not allowed\n",NULL);
  1376.                       c=-1;
  1377.                     }
  1378.                       else if ((OriginalSprite=Malloc(sizeof(*OriginalSprite)+strlen(Arguments.Type3.Filename)+1)))
  1379.                     {
  1380.                       OriginalSprite->Flags=SPRTF_ORIGINAL;
  1381.                       if (Arguments.Type3.NoImage)
  1382.                         {
  1383.                           OriginalSprite->Flags|=SPRTF_NOIMAGE;
  1384.                         }
  1385.                       if (Arguments.Type3.NoMask)
  1386.                         {
  1387.                           OriginalSprite->Flags|=SPRTF_NOMASK;
  1388.                         }
  1389.                       OriginalSprite->Number=SpriteNumber++;
  1390.                       OriginalSprite->Filename=(char *)(OriginalSprite+1);
  1391.                       strcpy(OriginalSprite->Filename,Arguments.Type3.Filename);
  1392.                       if (Arguments.Type3.Width)
  1393.                         OriginalSprite->Width=*Arguments.Type3.Width;
  1394.                       else
  1395.                         OriginalSprite->Width=0;
  1396.                       if (Arguments.Type3.Height)
  1397.                         OriginalSprite->Height=*Arguments.Type3.Height;
  1398.                       else
  1399.                         OriginalSprite->Height=0;
  1400.                       OriginalSprite->Next=OriginalSprites;
  1401.                       OriginalSprites=OriginalSprite;
  1402.                       if (Arguments.Type3.Label)
  1403.                         {
  1404.                           if ((OriginalSprite->Label=Malloc(strlen(Arguments.Type3.Label)+1)))
  1405.                         {
  1406.                           strcpy(OriginalSprite->Label,Arguments.Type3.Label);
  1407.                         }
  1408.                           else
  1409.                         {
  1410.                           c=-1;
  1411.                         }
  1412.                         }
  1413.                       else
  1414.                         {
  1415.                           OriginalSprite->Label=NULL;
  1416.                         }
  1417.                     }
  1418.                       else
  1419.                     {
  1420.                       c=-1;
  1421.                     }
  1422.                     }
  1423.                   else
  1424.                     {
  1425.                       VFPrintf(StdErr,"Invalid sprite description file\n",NULL);
  1426.                     }
  1427.                 }
  1428.                   else
  1429.                 {
  1430.                   PError(0,Name);
  1431.                 }
  1432.                 }
  1433.             }
  1434.               else
  1435.             {
  1436.               PError(0,Name);
  1437.             }
  1438.             }
  1439.           FreeArgs(RDArgs);
  1440.           SelectInput(OldInput);
  1441.         }
  1442.           else
  1443.         {
  1444.           PError(0,Name);
  1445.         }
  1446.         }
  1447.       else
  1448.         {
  1449.           if (IoErr())
  1450.         {
  1451.           PError(0,Name);
  1452.         }
  1453.           else
  1454.         {
  1455.           RC=TRUE;
  1456.         }
  1457.         }
  1458.     }
  1459.       while (c!=-1);
  1460.       Close(Filehandle);
  1461.     }
  1462.   else
  1463.     {
  1464.       PError(0,Name);
  1465.     }
  1466.   return RC;
  1467. }
  1468.  
  1469. /************************************************************************/
  1470. /*                                    */
  1471. /*                                    */
  1472. /************************************************************************/
  1473.  
  1474. int AmigaMain(void)
  1475.  
  1476. {
  1477.   int RC;
  1478.  
  1479.   RC=RETURN_CATASTROPHY;
  1480.   if (!WorkbenchMessage)
  1481.     {
  1482.       if ((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",ROM_VERSION)))
  1483.     {
  1484.       if ((UtilityBase=(struct UtilityBase *)OpenLibrary("utility.library",ROM_VERSION)))
  1485.         {
  1486.           if ((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",ROM_VERSION)))
  1487.         {
  1488.           RC=RETURN_FAIL;
  1489.           ErrorHandle();
  1490.           if ((MemoryPool=CreatePool(0,8192,8192)))
  1491.             {
  1492.               if ((ChipPool=CreatePool(0,16384,16384)))
  1493.             {
  1494.               if ((IFFParseBase=OpenLibrary("iffparse.library",36)))
  1495.                 {
  1496.                   struct RDArgs *RDArgs;
  1497.                   struct
  1498.                 {
  1499.                   const char *DescFile;
  1500.                   const char *ListFile;
  1501.                   const char *HeaderFile;
  1502.                   const char *SpriteDir;
  1503.                 } Arguments;
  1504.  
  1505.                   Arguments.DescFile="";
  1506.                   Arguments.HeaderFile=NULL;
  1507.                   Arguments.ListFile=NULL;
  1508.                   if ((RDArgs=ReadArgs("DESCFILE/A,LISTFILE,HEADERFILE,SPRITEDIR",(long *)&Arguments,NULL)))
  1509.                 {
  1510.                   if (ReadSpriteDesc(Arguments.DescFile))
  1511.                     {
  1512.                       if (CreateHeaderFile(Arguments.HeaderFile))
  1513.                     {
  1514.                       if (Arguments.ListFile)
  1515.                         {
  1516.                           BPTR DirLock;
  1517.  
  1518.                           if ((DirLock=Lock(Arguments.SpriteDir,SHARED_LOCK)))
  1519.                         {
  1520.                           DirLock=CurrentDir(DirLock);
  1521.                           RC=ReadSprites();
  1522.                           UnLock(CurrentDir(DirLock));
  1523.                           if (RC &&
  1524.                               MakeGraph() &&
  1525.                               RemoveDoubleFiles() &&
  1526.                               MakeColormap() &&
  1527.                               WriteSprites(Arguments.ListFile))
  1528.                             {
  1529.                               RC=RETURN_OK;
  1530.                             }
  1531.                           else
  1532.                             {
  1533.                               RC=RETURN_FAIL;
  1534.                             }
  1535.                         }
  1536.                           else
  1537.                         {
  1538.                           PError(0,Arguments.SpriteDir);
  1539.                         }
  1540.                         }
  1541.                       else
  1542.                         {
  1543.                           RC=RETURN_OK;
  1544.                         }
  1545.                     }
  1546.                     }
  1547.                   FreeArgs(RDArgs);
  1548.                 }
  1549.                   else
  1550.                 {
  1551.                   PError(0,NULL);
  1552.                 }
  1553.                   CloseLibrary(IFFParseBase);
  1554.                 }
  1555.               else
  1556.                 {
  1557.                   VFPrintf(StdErr,"Unable to open iffparse.library V36 or newer\n",NULL);
  1558.                 }
  1559.               DeletePool(ChipPool);
  1560.             }
  1561.               else
  1562.             {
  1563.               PError(0,NULL);
  1564.             }
  1565.               DeletePool(MemoryPool);
  1566.             }
  1567.           else
  1568.             {
  1569.               PError(0,NULL);
  1570.             }
  1571.           CloseStdErr();
  1572.           CloseLibrary(&GfxBase->LibNode);
  1573.         }
  1574.           CloseLibrary(&UtilityBase->ub_LibNode);
  1575.         }
  1576.       CloseLibrary(&DOSBase->dl_lib);
  1577.     }
  1578.     }
  1579.   return RC;
  1580. }
  1581.